home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr48
/
menu_u.zip
/
MENUMK.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-04-11
|
11KB
|
352 lines
Unit MenuMK;
{ Unit COPYRIGHT 1991 MARK KLAAMAS }
{ RELEASED TO PUBLIC DOMAIN ON 20 DECEMBER 1991 }
(**) Interface (**)
uses Crt;
const
MaxMsgLen = 40;
type
MessageString = String[MaxMsgLen];
EntryPointer = ^EntryType;
EntryType = Object
prev, next : EntryPointer;
Xcor, Ycor,
ChoiceNo : Integer;
Message : MessageString;
Constructor Init( iPr, iNx : EntryPointer;
iX, iY, iC : Integer;
iM : MessageString );
Procedure Draw( Selected : Boolean );
Function GetChoice : Integer;
end; { Object EntryType }
BBMenu = Object
Xcor, Ycor, Wid, Choices : Integer;
FirstEntry, Curentry : EntryPointer;
MenuTitle : String;
MenuStyle : Byte;
SideExit : Boolean;
Constructor Init(iX, iY, iW : Integer;
MTitle : String;
MenuC, HiC,
Style : byte;
SExit : Boolean);
Destructor Done;
Procedure AddPrompt( iM : MessageString);
Procedure Draw;
Function GetChoice : Integer;
end; { Object BBMenu }
Procedure MakeWindow( ULx, ULy, LRx, LRy, Color, CharType : Byte;
Banner : String;
Shadow : Boolean );
procedure WritePos( InStr : String; XCor, YCor : Byte);
procedure SetVideoAddress;
(**) Implementation (**)
{ Routine to get screen Type }
var
VidAddr : word; (* This variable will indicate the *)
(* memory address of the video-screen *)
(* array that we want to write our *)
(* string to. *)
(* Initialize the VidAddr variable. *)
procedure SetVideoAddress;
begin
if ((Mem[$0000:$0410] and $30) <> $30) then
VidAddr := $B800 (* Color video mode. *)
else
VidAddr := $B000; (* Monochrome video mode. *)
end;
procedure WritePos( InStr : String; XCor, YCor : Byte);
begin
GotoXY(XCor, YCor);
Write(InStr);
end; { procedure WritePos }
{ Window Routine used in unit. }
Procedure MakeWindow( ULx, ULy, LRx, LRy, Color, CharType : Byte;
Banner : String;
Shadow : Boolean );
var
VidOffset : Word; { Define memory area }
Len : Byte; { Define Length of block }
Width : Byte; { Define Width of block }
BorderChar: string[80]; { Define var for border }
Chars : String[8]; { Define the corners }
Center : Byte; { Define the center of box L-R }
begin
Window( ULx, ULy, LRx, LRy ); { Define Window bounds. }
TextAttr := Color;
ClrScr; { Fill Block With text color }
Window( 1, 1, 80, 25 );
{ Make the border for the window }
case CharType of
0 : Chars := '║═╔╗╚╝╠╣';
1 : Chars := '║─╓╖╙╜╟╢';
2 : Chars := '│═╒╕╘╛╞╡';
3 : Chars := '│─┌┐└┘├┤';
4 : Chars := ' ';
end;
{ TOP }
FillChar( BorderChar, LRx - ULx, Chars[2] ); { Fill In Middle }
BorderChar[0] := char(LRx - ULx);
Insert( Chars[3], BorderChar, 1 ); { Left Corner }
BorderChar[LRx - ULx +1] := Chars[4]; { Right Corner }
WritePos( BorderChar, ULx, ULy ); { Put BorderChar on SCR }
{ Middle }
BorderChar := Chars[1];
for Len := ULy + 1 to LRy - 1 do
begin
For Width := 1 to 2 do
begin
if Width = 1 then
WritePos(BorderChar, ULx, Len)
else
WritePos(BorderChar, LRx, Len);
end;
end;
{ Bottom }
FillChar( BorderChar, LRx - ULx, Chars[2] ); { Fill In Middle }
BorderChar[0] := char(LRx - ULx);
Insert( Chars[5], BorderChar, 1 ); { Left Corner }
BorderChar[LRx - ULx +1] := Chars[6]; { Right Corner }
WritePos( BorderChar, ULx, LRy ); { Put BorderChar on SCR }
if Shadow = True then { Okay Shadow wanted .. }
begin
if LRx < 80 - 2 then { Set condition for shadowing }
if LRy < 25 - 1 then { Make sure won't scroll }
begin
Width := 0; { Set var for shadow }
{ Do the Shadow on the right side }
For Len := 0 to (LRy - ULy - 1) do
begin
VidOffset := (80 * ((ULy + Len) * 2)) { Set Video Offset }
+ ((LRx) * 2) + 1;
While Width <= 2 do
begin
Mem[VidAddr : VidOffset + Width] := $08; { Actually write }
Inc( Width, 2 ); { on screen }
end;
Width := 0; { Reset the Width var }
end;
{ Do shadow on bottom }
Width := 0;
VidOffset := (80 * ((LRy) * 2)) { Set Video Offset }
+ ((ULx + Width + 1) * 2) + 1;
While Width < (LRx - Ulx + 1 ) * 2 do
begin
Mem[VidAddr : VidOffset + Width] := $08; { Actual write to screen }
Inc( Width, 2 );
end;
end;{ of Condition IF statement }
end; { of Shadowing section }
if Banner <> '' then
begin
{ Display Banner }
Center := ((LRx - ULx) div 2) - ((Length(Banner) div 2));
WritePos( Banner, ULx + Center, ULy + 1 );
{ Make line for botom of banner }
FillChar( BorderChar, LRx - ULx - 2, Chars[2] );
BorderChar[0] := Char( LRx - ULx - 1 );
Insert( Chars[7], BorderChar, 1 );
BorderChar := BorderChar + Chars[8];
WritePos( BorderChar, ULx, ULy + 2 );
end;
end; { procedure MakeWindow }
var
MenuColour, HiLight : Byte;
constructor BBMenu.Init(iX, iY, iW : Integer;
MTitle : string;
MenuC, HiC,
Style : byte;
SExit : Boolean);
begin
XCor := iX;
YCor := iY;
Wid := iW;
MenuTitle := MTitle; { Setup Title of Menu }
MenuStyle := Style; { Setup border type. }
MenuColour := MenuC; { Setup background colour }
HiLight := HiC; { Setup bounce bar colour }
SideExit := SExit; { Setup flag for sideexit }
if Wid > MaxMsgLen then
Wid := MaxMsgLen;
if Xcor + Wid > 80 then
Wid := 80 - XCor;
FirstEntry := NIL;
Choices := 0;
end; { constructor BBMenu.Init }
destructor BBMenu.Done;
begin
if FirstEntry <> NIL then
begin
FirstEntry^.Prev^.Next := Nil;
repeat
CurEntry := FirstEntry;
FirstEntry := FirstEntry^.Next;
Dispose(CurEntry);
until FirstEntry = NIL;
end;
end; { destructor BBMenu.Done }
procedure BBmenu.AddPrompt(iM : MessageString);
var
EP : EntryPointer;
begin
Inc(Choices);
{ pad with spaces }
FillChar(iM[length(iM) + 1], Wid - length(iM), #32);
iM[0] := char(Wid);
If FirstEntry = NIL then
begin
FirstEntry := New(EntryPointer, Init(NIL, NIL, XCor,
YCor + Choices - 1, Choices, iM));
FirstEntry^.Next := FirstEntry;
FirstEntry^.Prev := FirstEntry;
end
else
begin
EP := New(EntryPointer, Init(FirstEntry^.Prev, FirstEntry,
XCor, YCor + Choices - 1, Choices, iM));
FirstEntry^.Prev^.Next := EP;
FirstEntry^.Prev := EP;
end;
end; { procedure BBMenu.AddPrompt }
procedure BBMenu.Draw;
var ro, co : Byte;
begin
if MenuTitle = '' then
MakeWindow(XCor-1, YCor-1, XCor + Wid, YCor + Choices,
MenuColour, MenuStyle, '', True)
else
MakeWindow(XCor-1, YCor-3, XCor + Wid, YCor + Choices,
MenuColour, MenuStyle, MenuTitle, True);
CurEntry := FirstEntry;
repeat
CurEntry^.Draw(False);
CurEntry := CurEntry^.Next;
until CurEntry = FirstEntry;
end; { procedure BBMenu.Draw }
const
KEnter = $000D; KEsc = $001B;
KHome = $4700; KEnd = $4F00;
KLeft = $4B00; KRight = $4D00;
KDown = $5000; KUp = $4800;
function BBMenu.GetChoice : Integer;
var
SaveX, SaveY : Integer;
Finished : Boolean;
InChar : Char;
InWord : Word;
begin
SaveX := WhereX;
SaveY := WhereY;
TextAttr := MenuColour;
Draw;
Finished := False;
REPEAT
CurEntry^.Draw(True); { Write HI-Lighted option }
InChar := ReadKey;
If (InChar = #0) and KeyPressed then
begin
InChar := Readkey;
InWord := Word(InChar) SHL 8;
end
else
InWord := Ord(InChar);
CurEntry^.Draw(False);
case InWord of
kUp : CurEntry := CurEntry^.Prev;
kDown : CurEntry := CurEntry^.Next;
kHome : CurEntry := FirstEntry;
kEnd : CurEntry := FirstEntry^.Prev;
kLeft : if SideExit then
begin
Finished := True; { Left selected }
GetChoice := -1;
end;
kRight : If SideExit then
begin
Finished := True; { Right Selected }
GetChoice := -2;
end;
kEsc : begin
Finished := True;
GetChoice := 0;
end;
kEnter : begin
Finished := True;
GetChoice := CurEntry^.GetChoice;
end;
end;
until Finished;
GotoXY(SaveX, SaveY);
end;
constructor EntryType.Init(iPr, iNx : EntryPointer;
iX, iY, iC : Integer;
iM : MessageString);
begin
Prev := iPr;
Next := iNx;
Xcor := iX;
YCor := iY;
ChoiceNo := iC;
Message := iM;
end;
procedure EntryType.Draw(Selected : Boolean);
begin
If Selected then
TextAttr := HiLight
else
TextAttr := MenuColour;
WritePos(Message, Xcor, YCor);
end;
function EntryType.GetChoice : Integer;
begin
GetChoice := ChoiceNo;
end;
begin
SetVideoAddress;
end.